
 
#include "littlefs_port.h"



//#define BUFFER_SIZE 256

#define BLOCK_SIZE   4096

#define BOLCK_NUM 512  // 2M--512   8M--2048   16M--4096
#define LOOKAHEAD_SIZE (lfs_size_t)(BOLCK_NUM / 8)

lfs_t lfs;
lfs_file_t lfs_file;


static int lfs_flash_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size);
static int
lfs_flash_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size);
static int lfs_flash_erase(const struct lfs_config *c, lfs_block_t block);
static int lfs_flash_sync(const struct lfs_config *c);

const struct lfs_config cfg = {
	// block device operations
	.read = lfs_flash_read,
	.prog = lfs_flash_prog,
	.erase = lfs_flash_erase,
	.sync = lfs_flash_sync,

	// block device configuration
	.read_size = BUFFER_SIZE,
	.prog_size = BUFFER_SIZE,
	.block_size = BLOCK_SIZE,
	.block_count = BOLCK_NUM,
	.cache_size = BUFFER_SIZE,
	.lookahead_size = LOOKAHEAD_SIZE,
	.block_cycles = 500,
};


static int lfs_flash_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size)
{
	uint32_t addr;
	addr = ((uint32_t)block << (uint32_t)12);
	addr += off;

#ifdef enable_flash_debug
	char message[64];
	if(Flash_Debug_Flag)
	{
		memset(message, 0x00, sizeof(message));

		sprintf(message, "Flash Read Block is %d, Offset is %d, Size is %d\n\r", block, off, size);
		debug_log(message, strlen(message));
	}

#endif
	spi_flash_buffer_read((uint8_t *)buffer, addr, size);
	return LFS_ERR_OK;
}

static int lfs_flash_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size)
{
	uint32_t addr;
	addr = ((uint32_t)block << (uint32_t)12);
	addr += off;
// SPI_Flash_Write(addr, size, (uint8_t *)buffer);
#ifdef enable_flash_debug
	char message[64];
	if(Flash_Debug_Flag)
	{
		memset(message, 0x00, sizeof(message));

		sprintf(message, "Flash Prog Block is %d, Offset is %d, Size if %d\n\r", block, off, size);
		debug_log(message, strlen(message));
	}

#endif
	spi_flash_buffer_write((uint8_t *)buffer, addr, size);
	return LFS_ERR_OK;
}

static int lfs_flash_erase(const struct lfs_config *c, lfs_block_t block)
{
#ifdef enable_flash_debug
	char message[64];

	if(Flash_Debug_Flag)
	{
		memset(message, 0x00, sizeof(message));

		sprintf(message, "Erase Block is %d\n\r", block);
		debug_log(message, strlen(message));
	}

#endif
	spi_flash_sector_erase(block << 12);
	return LFS_ERR_OK;
}

static int lfs_flash_sync(const struct lfs_config *c)
{
	return LFS_ERR_OK;
}

void File_System_Init(void)
{
	int err;

	// lfs_format(&lfs, &cfg);
	err = lfs_mount(&lfs, &cfg);
	if(err)
	{
		lfs_format(&lfs, &cfg);
		err = lfs_mount(&lfs, &cfg);
	}
	if(err == 0)
	{
		printf("Littlefs is ok! \r\n");
	}
	else
	{
		printf("Littlefs is failer! \r\n");
	}
}

int8_t File_Write(char *name, uint8_t *dat, uint16_t bypass, uint16_t size)
{
	int err;

	err = lfs_file_open(&lfs, &lfs_file, name, LFS_O_RDWR | LFS_O_CREAT);
	if(err == LFS_ERR_OK)
	{
		lfs_file_seek(&lfs, &lfs_file, bypass, LFS_SEEK_SET);
		lfs_file_write(&lfs, &lfs_file, dat, size);
		lfs_file_close(&lfs, &lfs_file);
		return 0;
	}
	return -1;
}

lfs_size_t File_Read(char *name, uint8_t *dat, lfs_soff_t off, lfs_size_t size)
{
	lfs_size_t file_size;
	lfs_file_open(&lfs, &lfs_file, name, LFS_O_RDWR | LFS_O_CREAT);
	lfs_file_seek(&lfs, &lfs_file, off, LFS_SEEK_SET);
	file_size = lfs_file_read(&lfs, &lfs_file, dat, size);
	lfs_file_close(&lfs, &lfs_file);
	return file_size;
}

void littlefs_test(void)
{
	const char *test_write = "littlefs test char";
	char test_read[32];

	memset(test_read, 0x00, sizeof(test_read));

	File_Write("test1", (uint8_t *)test_write, 0, strlen(test_write));
	printf("Write %s into the flash \r\n", test_write);

	File_Read("test1", (uint8_t *)test_read, 0, sizeof(test_read));
	printf("read %s from the flash \r\n", test_read);
}
